package com.fanfan.example.springmvc;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.fanfan.example.model.JsonResult;
import com.fanfan.example.model.TestModel;

import lombok.extern.slf4j.Slf4j;

@Slf4j // log 注解
@RestController // 返回界面以字符串的形式
@RequestMapping(value = "/springmvc") // 路由映射
public class SpringmvcTest {
    @Value("http://www.cznovel.com")
    Resource url;

    /**
     * 获取springmvc 所有的@RequestMapping 对应的url
     * 
     * @Title getUrlMapping
     * @author 于国帅
     * @date 2018年9月7日 上午8:25:03
     * @param request
     * @return Object
     */
    @ResponseBody
    @RequestMapping("getUrlMapping")
    public Object getUrlMapping(HttpServletRequest request) {
        List<String> uList = new ArrayList<String>();// 存储所有url集合
        // WebApplicationContext springvc 的应用上下文 能够获取 getServletContext
        WebApplicationContext wac = (WebApplicationContext) request.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE);// 获取上下文对象
        // 获取 HandlerMapping 的map
        Map<String, HandlerMapping> requestMappings = BeanFactoryUtils.beansOfTypeIncludingAncestors(wac, HandlerMapping.class, true,
                false);
        for (HandlerMapping handlerMapping : requestMappings.values()) {
            if (handlerMapping instanceof RequestMappingHandlerMapping) {
                // 内部很深的水啊
                RequestMappingHandlerMapping rmhm = (RequestMappingHandlerMapping) handlerMapping;
                Map<RequestMappingInfo, HandlerMethod> handlerMethods = rmhm.getHandlerMethods();
                for (RequestMappingInfo rmi : handlerMethods.keySet()) {
                    PatternsRequestCondition prc = rmi.getPatternsCondition();
                    // 获取到了所有的url 因为不知道接下来干什么，所以暂时忽略掉
                    Set<String> patterns = prc.getPatterns();
                    for (String uStr : patterns)
                        uList.add(uStr + "<br/>");
                }
            }
        }
        return uList;
    }

    @RequestMapping(value = "/logExt", method = RequestMethod.GET)
    public String logExt() {
        System.err.println(url);
        System.err.println(url);

        return "logExt";
    }

    @RequestMapping(value = "/logExtAjax", method = RequestMethod.GET)
    @ResponseBody
    public String toAdd() {
        return "logExtAjax";
    }

    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public String get() {
        log.info("用的@RequestMapping get 访问的");
        return "用的@RequestMapping get 访问的";
    }

    @RequestMapping(value = "/post", method = RequestMethod.POST)
    public String post() {
        log.info("用的@RequestMapping post 访问的");
        return "用的@RequestMapping post 访问的";
    }

    @GetMapping(value = "/getMapping") // @GetMapping 组合注解，是@RequestMapping(method = RequestMethod.GET)的缩写
    public String getMapping() {
        log.info("用的@GetMapping get 访问的");
        return "用的@GetMapping get 访问的";
    }

    @PostMapping(value = "/postMapping") //
    public String postMapping() {
        log.info("用的@PostMapping post 访问的");
        return "用的@PostMapping post 访问的";
    }

    @RequestMapping(value = { "/mapping", "/mapping2" }) // 这边不设置方法，还是有很多属性的
    public String mapping() {
        String str = "测试数组形式访问" + "/mapping能访问到" + "/mapping2也能";
        log.info(str);
        return str;
    }

    @RequestMapping(value = { "/mappingParams/{id}" }) // 这边不设置方法，还是有很多属性的
    public String mappingParams(@PathVariable String id) {
        String str = "@PathVariable url=xxx/ss  时 获取的是ss ,id=" + id;
        log.info(str);
        return str;
    }

    @RequestMapping(value = { "/redirectTest" }) // 这边不设置方法，还是有很多属性的
    public String redirectTest(HttpServletResponse response) {
        String str = "redirectTest";
        log.info(str);
//        return "redirect:/redirectTest2"; //重定向方法1
        try {
            response.sendRedirect("/springmvc/redirectTest2");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } // 方法二
        return null;
    }

    @RequestMapping(value = { "/redirectTest2" }) // 这边不设置方法，还是有很多属性的
    public String redirectTest2() {
        String str = "redirectTest重定向过来了的";
        log.info(str);
        return str;
    }

    @RequestMapping(value = { "/jsonDate" }) // 这边不设置方法，还是有很多属性的
    @ResponseBody
    public Object jsonDate() {
        TestModel model = new TestModel();
        model.setTime(new Date());
        model.setJsonTime(new Date());
        return model;
    }

    @RequestMapping(value = { "/jsonDate2" }) // 这边不设置方法，还是有很多属性的
    @ResponseBody
    public Object jsonDate2() {
        TestModel model = new TestModel();
        model.setTime(new Date());
        model.setJsonTime(new Date());
        return JsonResult.sendOk(model);
    }
}
